import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

enum PanGestureDisposition {
  /// 默认处理
  unIntervene,

  /// 拦截全部触摸事件
  intercept,

  /// 不接收触摸事件
  abort
}

///自定义手势识别器
class CustomPanGestureRecognizer extends PanGestureRecognizer {
  //泛手势处置 默认处理
  PanGestureDisposition disposition = PanGestureDisposition.unIntervene;

  @override
  //添加指针事件方法
  void addPointer(PointerDownEvent event) {
    //泛手势处置 == 不接收触摸事件；则不添加事件
    if (disposition == PanGestureDisposition.abort) {
      return;
    }
    super.addPointer(event); //添加指针
    if (disposition == PanGestureDisposition.intercept) {
      //泛手势处置 == 拦截全部触摸事件；则不添加事件
      resolve(GestureDisposition.accepted); //解析 已经接受的手势处置
    }
  }
}

//类型定义 决定处置 =  泛手势处置 (指针向下事件)
typedef DecideDisposition = PanGestureDisposition Function(
    PointerDownEvent pointerDownEvent);

class PanGestureDetector extends StatefulWidget {
  final Widget child;
  final DecideDisposition? disposition; //决定处置
  final GestureDragDownCallback? onPanDown; //手势下拉回调
  final GestureDragStartCallback? onPanStart; //手势拖动开始回调

  final GestureDragUpdateCallback? onPanUpdate; //手势拖动更新回调

  final GestureDragEndCallback? onPanEnd; //手势拖拽结束回调
  final GestureDragCancelCallback? onPanCancel; //手势拖动取消回调

  const PanGestureDetector({
    Key? key,
    required this.child,
    this.disposition,
    this.onPanDown,
    this.onPanStart,
    this.onPanUpdate,
    this.onPanEnd,
    this.onPanCancel,
  }) : super(key: key);

  @override
  _PanGestureDetectorState createState() => _PanGestureDetectorState();
}

class _PanGestureDetectorState extends State<PanGestureDetector> {
  late CustomPanGestureRecognizer _panGestureRecognizer; //自定义平移手势识别器

  @override
  void initState() {
    super.initState();
    //实例化
    _panGestureRecognizer = CustomPanGestureRecognizer()
      ..onDown = widget.onPanDown
      ..onStart = widget.onPanStart
      ..onUpdate = widget.onPanUpdate
      ..onEnd = widget.onPanEnd
      ..onCancel = widget.onPanCancel;
  }

  @override
  Widget build(BuildContext context) {
    return Listener(
      //监听器
      behavior: HitTestBehavior.opaque, //不透明
      child: widget.child,
      onPointerDown: (event) {
        _panGestureRecognizer
          ..disposition = widget.disposition?.call(event) ??
              PanGestureDisposition.unIntervene
          ..addPointer(event); //添加指针
      },
    );
  }

  @override
  void dispose() {
    _panGestureRecognizer.dispose();
    super.dispose();
  }
}
